/**
 * 针对S2500跨路内存访问测试
 * @file crossCpuMemoryTest.c
 * @author yeqiang@greatwall.com.cn
 * @brief
 * @version 0.1
 * @date 2022-08-22
 *
 * @copyright Copyright (c) 2022
 *
 */
#define _GNU_SOURCE

#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <string.h>
#include <unistd.h>
#include <sys/time.h>
#include <sched.h>
#include <errno.h>
#include <pthread.h>

// 31GB
#define BUFF_SIZE 31 * 1024 * 1024 * 1024l

/* Return the UNIX time in microseconds */
long long ustime(void)
{
    struct timeval tv;
    long long ust;

    gettimeofday(&tv, NULL);
    ust = ((long long)tv.tv_sec) * 1000000;
    ust += tv.tv_usec;
    return ust;
}

void memoryTest(void *arg)
{
}

int main(int argc, char *argv[])
{
    pid_t pid = getpid();
    printf("pid=%d\n", pid);

    cpu_set_t mask;

    int cpuid = 0;
    while (1)
    {
        for (int i = 0; i <= 63; i++)
        {
            CPU_ZERO(&mask);
            CPU_SET(i, &mask);
            // 进程迁移到CPU i
            if (sched_setaffinity(0, sizeof(mask), &mask) == -1)
            {
                printf("绑定CPU出错, ERROR:%s\n", strerror(errno));
                return -1;
            }
            printf("CPU%d(node%d)\t", i, i / 8);
            fflush(stdout);
            // 申请内存
            char *srcBuff = (char *)malloc(BUFF_SIZE);
            printf("malloc\t");
            fflush(stdout);
            // 设置内存值
            int block = BUFF_SIZE / 1024;
            for (unsigned long t = 0; t < block; t++)
            {
                memset(srcBuff + t * 1024, t, 1024);
            }
            printf("memset\t");
            fflush(stdout);
            //进程迁移到 CPU i+64
            CPU_ZERO(&mask);
            CPU_SET(i + 64, &mask);
            printf("迁移到 CPU%d(node%d)\t", i + 64, (i + 64) / 8);
            fflush(stdout);
            // 进程迁移到CPU i
            if (sched_setaffinity(0, sizeof(mask), &mask) == -1)
            {
                printf("绑定CPU出错, ERROR:%s\n", strerror(errno));
                return -1;
            }
            char *destBuff = (char *)malloc(BUFF_SIZE);
            printf("malloc\t");
            fflush(stdout);
            // 跨路 从CPU i 复制对应内存数据到 CPU i+64
            memcpy(destBuff, srcBuff, BUFF_SIZE);
            printf("memcpy\t");
            fflush(stdout);
            // 重置destBuff
            memset(destBuff, i + 1, BUFF_SIZE);
            for (unsigned long t = 0; t < block; t++)
            {
                memset(destBuff + t * 1024, t + 1, 1024);
            }
            printf("memset2\t");
            fflush(stdout);
            // 反向复制一次
            memcpy(srcBuff, destBuff, BUFF_SIZE);
            printf("memcpy(反向)\t");
            fflush(stdout);
            //释放内存
            free(srcBuff);
            free(destBuff);
            printf("free\n");
            fflush(stdout);
        }
        printf("\n");
    }

    return 0;
}